
#pragma once
#include <d3dx9.h>
#include "goodlinklist.h"
#include <TextureItem.h>
#include "Character_define.h"

class CSkelMeshNode;
class _BoneList;
class _Anim;
class _Frame;
class _FrameNode;
class CSkeletonMesh;
class CCharacterBase;

class CModel
{
	friend class CModelRender;
public:
	CModel(/* CCharacterBase* pCharacter,*/ const int& iCharacterType,const int& iClass,const int& iIndex = 0);

	virtual ~CModel(void);

	CSkeletonMesh* GetSkeMeshByType(const int& iType);
	const D3DXMATRIX& GetTransMat() const
	{
		return m_matTrans;
	}

	D3DXMATRIX* GetMatRot()
	{
		return &m_matRot;
	}

	D3DXMATRIX* GetMatShadow()
	{
		return &m_matShadow;
	}

    int GetCharType() const
	{
		return m_iCharType;
	}

	void SetClass(const int& iClass)
	{
		m_iClass = iClass;
	}

	int GetClass() const
	{
		return m_iClass;
	}



	void SetRadius(const float& fRaduis)
	{
		if (fRaduis>m_fRadius)
		{
			m_fRadius = fRaduis;
			m_vec4Bottom.y = 0.5f/m_fRadius;
			m_vec4Bottom.z = 0.5f;
			m_vec4Bottom.w = 1.0f;
		}
	}
	inline float* GetBottom(const float& fBottomX)
	{
		m_vec4Bottom.x = fBottomX + m_matTrans._42;
		return (float*)&m_vec4Bottom;
	}

	inline const int GetOption() const
	{
		return m_iOption;
	}

	inline void SetOption(const int& iOption)
	{
		m_iOption = iOption;
	}

	inline void SetDistance(const float& fDis)
	{
		m_fDistance = fDis;
	}

	inline float GetDistance() const
	{
		return m_fDistance;
	}

	inline void SetPos(const float& fX,const float& fY,const float& fZ)
	{
		m_matTrans._41 = fX;
		m_matTrans._42 = fY;
		m_matTrans._43 = fZ;
	}

	inline const D3DXMATRIX* GetInterpolMat() const
	{
		return &m_matInterpol;
	}

	inline void GetPostion(D3DXVECTOR3& vec3Pos) const 
	{
		vec3Pos.x = m_matTrans._41;
		vec3Pos.y = m_matTrans._42;
		vec3Pos.z = m_matTrans._43;
	}
		
	int GetIndex() const
	{
		return m_iIndex;
	}
	void RunRotate(const float& fElapsedTime);
	void InitRotate(const D3DXVECTOR3 &dest);

	void Update(const float& fElapsedTime);

	/*iType is _SKELETONMESHTYPE*/
	BOOL SetTextureFactor(const int& iType,const int& iPartType,const DWORD& dwFactor);
	BOOL SetAnim(const int& iType, const int& iIndex,const _AniPlayOption& playOpt,
		const BOOL& bReset = FALSE,const int& iNameShare = _NAME_SHARE_NORMAL);

	BOOL ChangeBone(const int& iClass,const int& iType = _SMESH_WEAPON,const int& iBoneIndex = 0);
	BOOL ChangeMesh(const int& iPartType,const int& iIndex,const BOOL& bAdd);
	//name not include postfix!!!
	BOOL ChangeMesh(const int& iPartType,const char* pszSkinName,const char* pszTexName,const BOOL& bAdd);

	void RunAnimEvent(_AnimEvent* pEvent);
	BOOL SetAnimEvent(const _AniEventType& eType,const _AniEventFLag& eFlag,const int& iSklType  = _SMESH_GENERAL);

	const D3DXVECTOR3& GetMeshMin(const int& iParttype);
	const D3DXVECTOR3& GetMeshMax(const int& iParttype);

	inline void SetShadowMaxX(const float& fMax)
	{
		if (fMax>m_fShadowMaxX)
		{
			m_fShadowMaxX = fMax;
		}
	}

	inline void SetShadowMaxY(const float& fMax)
	{
		if (fMax>m_fShadowMaxY)
		{
			m_fShadowMaxY = fMax;
		}
	}

	void SetVisual(const BOOL& bVisual)
	{
		m_bVisual = bVisual;
	}

	const BOOL IsVisual() const
	{
		return m_bVisual;
	}

protected:


private:
	void Init( );

	CSkeletonMesh* AddSkelMesh(const int& iSkelType,const int& iBoneIndex);
	void InitPC();
	void InitNPC();

	void Term();


protected:
	int  m_iLODlevel;
	int  m_iRendMode;

	int  m_iColorLerp;
	float m_iClerp;
	float m_fClerpDeta;

	float m_fRotAngle;
	float m_fRadius;

	float m_fDamagehit;
	float m_fAlpha;

	int   m_iCharType;//_CHATYPE 
	int   m_iClass;
	int   m_iIndex;

	int   m_iOption;

	float m_fDistance;

	float m_fShadowMaxX;
	float m_fShadowMaxY;

	D3DXVECTOR4 m_vec4Spec;
	D3DXVECTOR4 m_vec4Diffuse;

	D3DXVECTOR4 m_vec4Hit;
	D3DXVECTOR4 m_vec4Bottom;

	D3DXMATRIX m_matTrans;
	D3DXMATRIX m_matRot;
	D3DXMATRIX m_matRotOrig;
	D3DXMATRIX m_matShadow;
	CGLinkedList<CSkeletonMesh*> m_listSkeletoMesh;



private:	
	BOOL  m_bVisual;
	BOOL  m_bSlerpRot;
	float m_fRotateLerp;
	D3DXQUATERNION m_quaRotSlerpStart;
	D3DXQUATERNION m_quaRotSlerpEnd;
	D3DXMATRIX     m_matInterpol;

	CCharacterBase* m_pCharacter;

};
